import random as rd
import math as mt
import numpy as np
from scipy.spatial import Delaunay
import matplotlib.pyplot as plt
max_dis = 1e3
def make_G(n1, n2, alpha_b = 1.0, alpha_c = 0.5):
    N = n1
    G  = np.zeros((N , N ))
    G1 = np.zeros((n1, n1))
    G2 = np.zeros((n2, n2))
    for i in range(0, n1):
        for j in range(i + 1, n1):
            G[i][j] = G[j][i] = max_dis
            G1[i][j] = G1[j][i] = max_dis
    for i in range(0, n2):
        for j in range(i + 1, n2):
            G2[i][j] = G2[j][i] = max_dis
    min_dis = 1.0 / (3.0 * mt.sqrt(n1))
    point_list = []
    while(len(point_list) < n1):
        # if(len(point_list) % 10 == 0):
        #     print(len(point_list))
        rd_x = rd.random()
        rd_y = rd.random()
        rd_p = np.array([rd_x, rd_y])
        flag = 1
        for p in point_list:
            #print(p)
            if(np.linalg.norm(p - rd_p) < min_dis):
                flag = 0
                break
        if(flag == 1):
            point_list.append(rd_p)
            #print(rd_p)
    point_list = np.array(point_list)
    tri = Delaunay(point_list)
    edge1 = tri.simplices.copy()
    for t in edge1:
        #print(t, t[0], t[1], t[2])
        G[t[0]][t[1]] = G[t[1]][t[0]] = G1[t[0]][t[1]] = G1[t[1]][t[0]] = alpha_b * np.linalg.norm(point_list[t[0]] - point_list[t[1]])
        G[t[1]][t[2]] = G[t[2]][t[1]] = G1[t[1]][t[2]] = G1[t[2]][t[1]] = alpha_b * np.linalg.norm(point_list[t[2]] - point_list[t[1]])
        G[t[0]][t[2]] = G[t[2]][t[0]] = G1[t[0]][t[2]] = G1[t[2]][t[0]] = alpha_b * np.linalg.norm(point_list[t[0]] - point_list[t[2]])
        #print(G[t[0]][t[1]], G[t[1]][t[2]], G[t[0]][t[2]])
    #print(G)
    #print(len(edge1))
    pointID = [j for j in range(0, n1)]
    #point2ID = []
    point_list2 = []
    while(len(point_list2) < n2):
        p2 = rd.choice(pointID)
        point_list2.append(point_list[p2])
        pointID.remove(p2)
        #point2ID.append(p2)
    point_list2 = np.array(point_list2)
    tri2 = Delaunay(point_list2)
    edge2 = tri2.simplices.copy()
    #print(len(edge2))
    for t in edge2:
        G[t[0]][t[1]] = G[t[1]][t[0]] = G2[t[0]][t[1]] = G2[t[1]][t[0]] = alpha_c * np.linalg.norm(point_list2[t[0]] - point_list2[t[1]])
        G[t[1]][t[2]] = G[t[2]][t[1]] = G2[t[1]][t[2]] = G2[t[2]][t[1]] = alpha_c * np.linalg.norm(point_list2[t[2]] - point_list2[t[1]])
        G[t[0]][t[2]] = G[t[2]][t[0]] = G2[t[0]][t[2]] = G2[t[2]][t[0]] = alpha_c * np.linalg.norm(point_list2[t[0]] - point_list2[t[2]])
    # print(tri)
    #print(G)
    #print(G1)
    # plt.triplot(point_list2[:,0], point_list2[:,1], tri2.simplices.copy())
    # plt.plot(point_list2[:,0], point_list2[:,1], 'o')
    # plt.show()
    # plt.triplot(point_list[:,0], point_list[:,1], tri.simplices.copy())
    # plt.plot(point_list[:,0], point_list[:,1], 'o')
    # plt.show()
    # for i in range(len(point2ID)):#???
    #     G[point2ID[i]][n1 + i] = G[n1 + i][point2ID[i]] = 0
    # cnt = 0
    # for i in range(len(G)):
    #     for j in range(len(G)):
    #         if(G[i][j] > 0 and G[i][j] < 1e3):
    #                 cnt += 1
    # print(cnt)
    return G, G1, G2
def make_T1(G, n1, n2):#?????
    N = len(G)
    T = np.zeros((N, N))
    dest = [i for i in range(0, n1)]
    dest = rd.choice(dest)
    sum_rd = 0
    for i in range(0, n1):
        if(i == dest): continue
        T[i][dest] = rd.random()
        sum_rd += T[i][dest]
    T /= sum_rd
    return T, dest

def make_T2(T, p, n1, n2, dest):#????
    new_dest = [i for i in range(0, n1)]
    new_dest.remove(dest)
    for i in range(0, n1):
        r = rd.random()
        if(r < p):
            T[i][rd.choice(new_dest)] = T[i][dest]
            T[i][dest] = 0
    return T
